package czopyk.model.factories;

import org.apache.log4j.Logger;

import czopyk.model.analysis.Analyzer;
import czopyk.model.cost.CostMapper;
import czopyk.model.cost.DistributionManager;
import czopyk.model.cost.InterferenceManager;
import czopyk.model.persistence.Controller;
import czopyk.model.persistence.Serializer;
import czopyk.model.structure.LoadGenerator;
import czopyk.model.structure.LoadSelector;
import czopyk.model.structure.Modulator;
import czopyk.model.structure.Simulator;
import czopyk.model.validation.Validator;

public class Locator {
	
	private static final Logger lgr = Logger.getLogger(Locator.class);
	
	private static CenterFactory centerFactory = new CenterFactory();
	
	private static CostMapper costMapper = new CostMapper();
	
	private static Validator validator = new Validator();
	
	private static RequestFactory requestFactory = new RequestFactory();
	
	private static LoadGenerator loadGenerator = new LoadGenerator();
	
	private static Simulator simulator = new Simulator();
	
	private static LoadSelector loadSelector = new LoadSelector();

	private static Modulator modulator = new Modulator();

	private static Analyzer analyzer = new Analyzer();

	private static DistributionManager distributionManager = new DistributionManager();
	
	private static InterferenceManager interferenceManager = new InterferenceManager();
	
	private static boolean initialized = false;
	
	public static void loadSimulation(final String modelConfigFilename,
			String controllerFilename) throws Exception {
		
		requestFactory.setDistributionManager(distributionManager);
		
		loadSelector.setRf(requestFactory);
		
		loadGenerator.setLoadSelector(loadSelector);
		loadGenerator.setDistributionManager(distributionManager);
		loadGenerator.setSimulator(simulator);
		
		modulator.setLoadGenerator(loadGenerator);
		modulator.setSimulator(simulator);
		modulator.setDistributionManager(distributionManager);
		
		simulator.setAnalyzer(analyzer);
	
		costMapper.setDistributionManager(distributionManager);
		
		validator.setCostMapper(costMapper);
		validator.setLoadSelector(loadSelector);

		final Serializer s = new Serializer(modelConfigFilename);
		simulator.setGate(s.getGate());
		
		lgr.info("Context initialized");

		initialized = true;
		
		new Controller().load(controllerFilename);
		
		simulator.initSimulation();
		loadGenerator.run();
	}
	
	private static void checkInitialization() {
		if (!initialized) {
			throw new IllegalStateException("Locator not initialized!");
		}
	}
	
	public static CostMapper getCostMapper() {
		return costMapper;
	}
	
	public static Validator getValidator() {
		return validator;
	}

	// tylko to trzeba inicjalizować!
	public static Simulator getSimulator() {
		checkInitialization();
		return simulator;
	}

	public static LoadGenerator getLoadGenerator() {
		return loadGenerator;
	}
	
	public static LoadSelector getLoadSelector() {
		return loadSelector;
	}

	public static Analyzer getAnalyzer() {
		return analyzer;
	}

	public static Modulator getModulator() {
		return modulator;
	}

	public static RequestFactory getRequestFactory() {
		return requestFactory;
	}

	public static CenterFactory getCenterFactory() {
		return centerFactory;
	}

	public static DistributionManager getDistributionManager() {
		return distributionManager;
	}

	public static InterferenceManager getInterferenceManager() {
		return interferenceManager;
	}

}
